import pygtk
pygtk.require('2.0')
import gtk


def _save_pane_positions(node):
    node

def XpmPixmap(width, height, colors, rows):
    lines = ["%d %d %d 1" % (width, height, len(colors))]
    for chr, clr in colors.iteritems():
        lines.append("%s c %s" % (chr, clr))
    lines.extend(rows)
    return gtk.gdk.pixbuf_new_from_xpm_data(lines)

icon = XpmPixmap(17, 16, 
    {
        " " : "#000000", 
        "." : "#808000", 
        "X" : "yellow", 
        "o" : "#808080", 
        "O" : "#c0c0c0", 
        "+" : "white",
        "@" : "None", 
    }, 
    [
        "@@@@@@@@@@@@@@@@@",
        "@@@@@@@@@@@@@@@@@",
        "@@+XXXX.@@@@@@@@@",
        "@+OOOOOO.@@@@@@@@",
        "@+OXOXOXOXOXOXO. ",
        "@+XOXOXOXOXOXOX. ",
        "@+OXOXOXOXOXOXO. ",
        "@+XOXOXOXOXOXOX. ",
        "@+OXOXOXOXOXOXO. ",
        "@+XOXOXOXOXOXOX. ",
        "@+OXOXOXOXOXOXO. ",
        "@+XOXOXOXOXOXOX. ",
        "@+OOOOOOOOOOOOO. ",
        "@                ",
        "@@@@@@@@@@@@@@@@@",
        "@@@@@@@@@@@@@@@@@",
    ]
)

def Window(title, child, resizable = True, menu = None, accel = None):
    obj = gtk.Window(gtk.WINDOW_TOPLEVEL)
    obj.set_title(title)
    obj.set_icon(icon)
    obj.set_resizable(resizable)  
    obj.connect("destroy", gtk.main_quit)

    if menu is not None:
        child2 = gtk.VBox()
        child2.pack_start(menu, expand=False, fill=False)
        child2.pack_start(child)
        child2.show()
        child = child2
    if accel is not None:
        obj.add_accel_group(accel)
    
    obj.add(child)
    return obj

def Menu(name, *children):
    obj = gtk.Menu()
    for child in children:
        obj.append(child)
    obj2 = gtk.MenuItem(name)
    obj2.set_submenu(obj)
    obj2.show()
    return obj2

def MenuItem(name, shortcut = None, action = None):
    obj = gtk.MenuItem(name)
    if action is not None:
        obj.connect("activate", action, None)
    obj.show()
    return obj

def MenuSep():
    obj = gtk.SeparatorMenuItem()
    obj.show()
    return obj

def MenuBar(*menus):
    obj = gtk.MenuBar()
    for mitem in menus:
        obj.append(mitem)
    obj.show()
    return obj

def Fixed(child):
    obj = gtk.VBox()
    obj2 = gtk.HBox()
    obj2.pack_start(child, expand = False, fill = False)
    obj2.show()
    obj.pack_start(obj2, expand = False, fill = False)
    obj.show()
    return obj

def _pack_paned(panefactory, children):
    if len(children) == 1:
        return children[0]
    p = panefactory()
    p.pack1(children[0])
    p.pack2(_pack_paned(panefactory, children[1:]))
    p.show()
    return p

def _get_kwargs(__values, **kwargs):
    res = dict((k, __values.pop(k, v)) for k, v in kwargs.iteritems())
    if __values:
        raise TypeError("got unexpected keyword arguments: %r" % (__values.keys(),))
    return res

def HBox(*children, **kwargs):
    kwargs = _get_kwargs(kwargs, spacing = 0)
    obj = gtk.HBox(spacing = kwargs["spacing"])
    if not children:
        return obj
    obj.pack_start(_pack_paned(gtk.HPaned, children))
    obj.show()
    return obj

def VBox(*children, **kwargs):
    kwargs = _get_kwargs(kwargs, spacing = 0)
    obj = gtk.HBox(spacing = kwargs["spacing"])
    if not children:
        return obj
    obj.pack_start(_pack_paned(gtk.VPaned, children))
    obj.show()
    return obj

def Label(text):
    obj = gtk.Label(text)
    obj.show()
    return obj

def TextLine(text = ""):
    obj = gtk.Entry()
    obj.set_text(text)
    obj.show()
    return obj

def Button(text):
    obj = gtk.Button(text)
    obj.show()
    return Fixed(obj)

def Scrolled(child):
    obj = gtk.ScrolledWindow()
    obj.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    obj.show()
    obj.add(child)
    return obj

def TextBox(text = "", readonly = False, scrolled = True):
    obj = gtk.TextView()
    if text:
        buf = obj.get_buffer()
        buf.set_text(text)
    obj.set_editable(not readonly)
    obj.show()
    if scrolled:
        obj = Scrolled(obj)
    return obj

import itertools

class TreeModel(gtk.GenericTreeModel):
    def __init__(self):
        gtk.GenericTreeModel.__init__(self)
        self.columns = [] # tuples of (columnobj, type, getter)
    
    def on_get_n_columns(self):
        return len(self.columns)
    def on_get_column_type(self, index):
        return self.columns[index][1]
    def on_get_iter(self, path):
        return path  # rowref <-> path are the same here
    def on_get_path(self, path):
        return path
    def on_get_value(self, path, index):
        return self.columns[index][2](path)
    def on_iter_children(self, path):
        return self.on_iter_nth_child(path, 0)
    def on_iter_has_child(self, path):
        return self.on_iter_n_children(path) > 0
    def on_iter_next(self, path):
        parent = self.on_iter_parent(path)
        if path[-1]+1 >= self.on_iter_n_children(parent):
            return None
        return self.on_iter_nth_child(parent, path[-1]+1)
    def on_iter_parent(self, path):
        return path[:-1]
    def on_get_flags(self):
        return gtk.TREE_MODEL_ITERS_PERSIST
    def on_iter_n_children(self, path):
        if path is None:
            path = ()
        return self.get_number_of_children(path)
    def on_iter_nth_child(self, path, n):
        if path is None:
            path = ()
        if n >= self.on_iter_n_children(path):
            return None
        return tuple(path) + (n,)
    
    def get_number_of_children(self, path):
        # implement me
        raise NotImplementedError()
    
    def append_column(self, title, type, getter):
        column_id = len(self.columns) 
        cell = gtk.CellRendererText()
        column = gtk.TreeViewColumn(title)
        column.pack_start(cell, True)
        column.add_attribute(cell, 'text', column_id)
        column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
        column.set_resizable(True)
        #tree.append_column(column)
        self.columns.append((column, type, getter))
        return column

def TreeView(model, scrolled = True, search = True):
    obj = gtk.TreeView(model)
    obj.set_enable_search(search)
    obj.show()
    if scrolled:
        obj = Scrolled(obj)
    return obj

def Frame(title, child):
    obj = gtk.Frame(title)
    obj.add(child)
    obj.show()
    return obj

def MessageBox(text):
    obj = gtk.MessageDialog(buttons = gtk.BUTTONS_OK, 
        type = gtk.MESSAGE_ERROR, 
        flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, 
        message_format=text)
    return obj
    #m.run()
    #m.destroy()

def AccelKey(func, key, ctrl = False, alt = False, meta = False, shift = False):
    flags = 0
    flags |= gtk.gdk.CONTROL_MASK if ctrl else 0
    flags |= gtk.gdk.MOD1_MASK if alt else 0
    flags |= gtk.gdk.META_MASK if meta else 0
    flags |= gtk.gdk.SHIFT_MASK if shift else 0
    return (func, key, flags)

def AccelGroup(*keys):
    obj = gtk.AccelGroup()
    for func, key, flags in keys:
        obj.connect_group(key, flags, 0, lambda *args: func)
    return obj





